package com.bookstore.service.impl;

import com.bookstore.dto.LoginDTO;
import com.bookstore.dto.UserDTO;
import com.bookstore.entity.User;
import com.bookstore.repository.UserRepository;
import com.bookstore.security.JwtTokenProvider;
import com.bookstore.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    @Lazy
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private JwtTokenProvider jwtTokenProvider; // 注入JWT提供者
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    }
    @Override
    @Transactional
    public UserDTO register(UserDTO userDTO) {
        if (userRepository.existsByUsername(userDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        if (userRepository.existsByEmail(userDTO.getEmail())) {
            throw new RuntimeException("邮箱已被注册");
        }
        User user = new User();
        user.setUsername(userDTO.getUsername());
        user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        user.setEmail(userDTO.getEmail());
//        user.setPhone(userDTO.getPhone());
//        user.setAddress(userDTO.getAddress());
        user.setRole("USER");
        user.setCreatedAt(LocalDateTime.now());
        User savedUser = userRepository.save(user);
        return convertToDTO(savedUser);
    }
    @Override
    public UserDTO getUserById(Long id) {
        return userRepository.findById(id)
                .map(this::convertToDTO)
                .orElseThrow(() -> new RuntimeException("User not found"));
    }
    @Override
    @Transactional
    public UserDTO updateUser(Long id, UserDTO userDTO) {
        return userRepository.findById(id)
                .map(user -> {
                    if (!user.getUsername().equals(userDTO.getUsername()) &&
                            userRepository.existsByUsername(userDTO.getUsername())) {
                        throw new RuntimeException("Username already exists");
                    }
                    if (!user.getEmail().equals(userDTO.getEmail()) &&
                            userRepository.existsByEmail(userDTO.getEmail())) {
                        throw new RuntimeException("Email already exists");
                    }
                    user.setUsername(userDTO.getUsername());
                    user.setEmail(userDTO.getEmail());
//                    user.setPhone(userDTO.getPhone());
//                    user.setAddress(userDTO.getAddress());
                    return convertToDTO(userRepository.save(user));
                })
                .orElseThrow(() -> new RuntimeException("User not found"));
    }
    @Override
    @Transactional
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
    @Override
    public List<UserDTO> getAllUsers() {
        return userRepository.findAll().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    @Override
    public UserDTO getCurrentUser() {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        return userRepository.findByUsername(username)
                .map(this::convertToDTO)
                .orElseThrow(() -> new RuntimeException("User not found"));
    }
    @Override
    @Transactional
    public void changePassword(Long userId, String oldPassword, String newPassword) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("User not found"));

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException("Old password is incorrect");
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(user);
    }
    @Override
    public boolean checkEmailExists(String email) {
        return userRepository.existsByEmail(email);
    }
    @Override
    public boolean checkUsernameExists(String username) {
        return userRepository.existsByUsername(username);
    }
    @Override
    public ResponseEntity<?> login(LoginDTO loginDTO) {
        try {
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            loginDTO.getUsername(),
                            loginDTO.getPassword()
                    )
            );
            SecurityContextHolder.getContext().setAuthentication(authentication);
            User user = (User) authentication.getPrincipal();
            
            // 生成JWT令牌
            String token = jwtTokenProvider.generateToken(user);
            
            // 转换为DTO并设置token
            UserDTO userDTO = convertToDTO(user);
            userDTO.setToken(token);

            return ResponseEntity.ok(userDTO);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body("登录失败：用户名或密码错误");
        }
    }
    @Override
    public ResponseEntity<?> getCurrentUserProfile() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth == null || !auth.isAuthenticated() || auth.getPrincipal().equals("anonymousUser")) {
            return ResponseEntity.badRequest().body("用户未登录");
        }

        try {
            User user = (User) auth.getPrincipal();
            return ResponseEntity.ok(convertToDTO(user));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body("获取用户信息失败");
        }
    }
    /**
     * 将 User 实体转换为 UserDTO
     */
    public UserDTO convertToDTO(User user) {
        if (user == null) {
            return null;
        }
        
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        // 出于安全考虑，不设置密码
        userDTO.setNickname(user.getNickname());
        userDTO.setEmail(user.getEmail());
        userDTO.setPhone(user.getPhone());
        userDTO.setAddress(user.getAddress());
        userDTO.setProvince(user.getProvince());
        userDTO.setCity(user.getCity());
        userDTO.setDistrict(user.getDistrict());
        userDTO.setZipCode(user.getZipCode());
        userDTO.setRole(user.getRole());
        
        return userDTO;
    }
    
    /**
     * 将 UserDTO 转换为 User 实体
     */
    public User convertToEntity(UserDTO userDTO) {
        if (userDTO == null) {
            return null;
        }
        
        User user = new User();
        user.setId(userDTO.getId());
        user.setUsername(userDTO.getUsername());
        
        // 只有在密码不为空时才设置密码
        if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
            // 如果需要加密密码，在这里处理
            user.setPassword(userDTO.getPassword());
        }
        
        user.setNickname(userDTO.getNickname());
        user.setEmail(userDTO.getEmail());
        user.setPhone(userDTO.getPhone());
        user.setAddress(userDTO.getAddress());
        user.setProvince(userDTO.getProvince());
        user.setCity(userDTO.getCity());
        user.setDistrict(userDTO.getDistrict());
        user.setZipCode(userDTO.getZipCode());
        user.setRole(userDTO.getRole());
        
        return user;
    }
    
    /**
     * 更新用户信息
     */
    public User updateUserFromDTO(User user, UserDTO userDTO) {
        // 只更新非空字段
        if (userDTO.getUsername() != null) {
            user.setUsername(userDTO.getUsername());
        }
        
        if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
            // 如果需要加密密码，在这里处理
            user.setPassword(userDTO.getPassword());
        }
        
        if (userDTO.getNickname() != null) {
            user.setNickname(userDTO.getNickname());
        }
        
        if (userDTO.getEmail() != null) {
            user.setEmail(userDTO.getEmail());
        }
        
        if (userDTO.getPhone() != null) {
            user.setPhone(userDTO.getPhone());
        }
        
        if (userDTO.getAddress() != null) {
            user.setAddress(userDTO.getAddress());
        }
        
        if (userDTO.getProvince() != null) {
            user.setProvince(userDTO.getProvince());
        }
        
        if (userDTO.getCity() != null) {
            user.setCity(userDTO.getCity());
        }
        
        if (userDTO.getDistrict() != null) {
            user.setDistrict(userDTO.getDistrict());
        }
        
        if (userDTO.getZipCode() != null) {
            user.setZipCode(userDTO.getZipCode());
        }
        
        if (userDTO.getRole() != null) {
            user.setRole(userDTO.getRole());
        }
        
        return user;
    }
}